#include <vtkActor.h>
#include <vtkActor2D.h>
#include <vtkCamera.h>
#include <vtkCellArray.h>
#include <vtkDataSetMapper.h>
#include <vtkGlyph3DMapper.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPoints.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkTextMapper.h>
#include <vtkTextProperty.h>
#include <vtkUnstructuredGrid.h>

#include <vtkHexagonalPrism.h>
#include <vtkHexahedron.h>
#include <vtkLine.h>
#include <vtkPentagonalPrism.h>
#include <vtkPixel.h>
#include <vtkPolyLine.h>
#include <vtkPolyVertex.h>
#include <vtkPolygon.h>
#include <vtkPyramid.h>
#include <vtkQuad.h>
#include <vtkTetra.h>
#include <vtkTriangle.h>
#include <vtkTriangleStrip.h>
#include <vtkVertex.h>
#include <vtkVoxel.h>
#include <vtkWedge.h>
#include <vtkPolyDataMapper.h>
#include <vtkAxisActor.h>
#include <vtkAxisActor2D.h>
#include <vtkAxis.h>
#include "vtkMapper2D.h"
#include "vtkAlgorithm.h"
#include "vtkPolyDataMapper2D.h"
#include "vtkProperty2D.h"
#include "vtkConeSource.h"

#include <cstdlib>
#include <string>
#include <vector>


int main(int, char*[])
{
    vtkNew<vtkNamedColors> colors;

    vtkNew<vtkRenderWindow> renWin;
    renWin->SetSize(600, 600);
    renWin->SetWindowName("LinearCellDemo");

    vtkNew<vtkRenderWindowInteractor> iRen;
    iRen->SetRenderWindow(renWin);

    vtkNew<vtkRenderer> renderer;
    renWin->AddRenderer(renderer);


    vtkNew<vtkSphereSource> sphere;
    sphere->SetPhiResolution(21);
    sphere->SetThetaResolution(21);
    sphere->SetRadius(.08);
    vtkNew<vtkPolyDataMapper> sphereMapper;
    sphereMapper->SetInputConnection(sphere->GetOutputPort());
    vtkNew<vtkActor> sphereActor;
    sphereActor->SetMapper(sphereMapper);
//    renderer->AddActor(sphereActor);


    // 2d

    vtkNew<vtkTextMapper> textMapper;
    vtkNew<vtkActor2D> textActor;
    std::string title = "aaaaa";
    textMapper->SetInput(title.c_str());
    textActor->SetMapper(textMapper);
    textActor->SetPosition(50, 10);
    renderer->AddViewProp(textActor);


//    vtkNew<vtkAxisActor> axis;
//    axis->SetPoint1(0, 0, 0);
//    axis->SetPoint2(150, 50, 0);
//    renderer->AddActor(axis);

//    vtkNew<vtkAxisActor2D> axis1;
//    axis1->SetPoint1(0, 0);
//    axis1->SetPoint2(50, 50);
////    renderer->AddActor(axis1);
//    renderer->AddViewProp(axis1);


    // Setup four tubeFilter2
    vtkNew<vtkPoints> points;
    points->InsertNextPoint(0.0, 0.0, 0.0);
    points->InsertNextPoint(1.0, 0.0, 0.0);
    points->InsertNextPoint(1.0, 1.0, 0.0);
    points->InsertNextPoint(0.0, 1.0, 0.0);

    // Create the polygon
    vtkNew<vtkPolygon> polygon;
    polygon->GetPointIds()->SetNumberOfIds(4); // make a quad
    polygon->GetPointIds()->SetId(0, 0);
    polygon->GetPointIds()->SetId(1, 1);
    polygon->GetPointIds()->SetId(2, 2);
    polygon->GetPointIds()->SetId(3, 3);

    vtkNew<vtkCellArray> polygons;
    polygons->InsertNextCell(polygon);
//    polygons->InsertNextCell(curve);

    // Create a PolyData
    vtkNew<vtkPolyData> polygonPolyData;
    polygonPolyData->SetPoints(points);
    polygonPolyData->SetPolys(polygons);

//    vtkNew<vtkPolyDataMapper> mapper;
//    mapper->SetInputData(polygonPolyData);

//    vtkNew<vtkActor> actor;
//    actor->SetMapper(mapper);
//    actor->GetProperty()->EdgeVisibilityOn();
//    renderer->AddActor(actor);


    vtkNew<vtkPolyDataMapper2D> mapper2d;
//    mapper2d->SetInputConnection(sphere->GetOutputPort());
        mapper2d->SetInputData(polygonPolyData);
    // TODO:必须设置转换坐标系系统
    vtkSmartPointer<vtkCoordinate> normCoords = vtkSmartPointer<vtkCoordinate>::New();
    normCoords->SetCoordinateSystemToView();
    mapper2d->SetTransformCoordinate( normCoords );

    vtkNew<vtkActor2D> actor2d;
    actor2d->SetMapper(mapper2d);
    actor2d->GetProperty()->SetColor( 1, 0, 0 );
    actor2d->GetProperty()->SetLineWidth( 1 );
    renderer->AddActor2D( actor2d );

    vtkSmartPointer<vtkCamera> camera = renderer->GetActiveCamera();
    renderer->ResetCamera();
    camera->SetParallelScale(100.0);
    camera->ParallelProjectionOn();

    iRen->Initialize();
    renWin->Render();
    iRen->Start();







//    vtkSmartPointer<vtkConeSource> cone =
//            vtkSmartPointer<vtkConeSource>::New();
//
//    vtkSmartPointer<vtkPolyDataMapper> mapper =
//            vtkSmartPointer<vtkPolyDataMapper>::New();
//    mapper->SetInputConnection( cone->GetOutputPort() );
//
//    vtkSmartPointer<vtkActor> actor =
//            vtkSmartPointer<vtkActor>::New();
//    actor->SetMapper( mapper );
//
//    vtkSmartPointer<vtkRenderer> renderer =
//            vtkSmartPointer<vtkRenderer>::New();
//    renderer->AddActor(actor);
//    renderer->SetBackground( 0, 0, 0 );
//
//    vtkSmartPointer<vtkRenderWindow> renderWindow =
//            vtkSmartPointer<vtkRenderWindow>::New();
//    renderWindow->AddRenderer( renderer );
//
//    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
//            vtkSmartPointer<vtkRenderWindowInteractor>::New();
//    renderWindowInteractor->SetRenderWindow( renderWindow );
//
//    // ------------- start to add red line ----------------
//    vtkSmartPointer<vtkPolyDataMapper2D> v1mmMapper = vtkSmartPointer<vtkPolyDataMapper2D>::New();
//    vtkSmartPointer<vtkPolyData> v1mmPolyData = vtkSmartPointer<vtkPolyData>::New();
//    vtkSmartPointer<vtkCellArray> v1mmLines = vtkSmartPointer<vtkCellArray>::New();
//    vtkSmartPointer<vtkPoints> v1mmPoints = vtkSmartPointer<vtkPoints>::New();
//
//    v1mmPolyData->SetPoints( v1mmPoints );
//    v1mmPolyData->SetLines( v1mmLines );
//    v1mmMapper->SetInputData( v1mmPolyData );
//
//    vtkSmartPointer<vtkActor2D> v1mmLinesActor = vtkSmartPointer<vtkActor2D>::New();
//    v1mmLinesActor->SetMapper( v1mmMapper );
//    v1mmLinesActor->GetProperty()->SetColor( 1, 0, 0 );
//    v1mmLinesActor->GetProperty()->SetLineWidth( 1 );
//
//    vtkSmartPointer<vtkCoordinate> normCoords = vtkSmartPointer<vtkCoordinate>::New();
//    normCoords->SetCoordinateSystemToView();
//    v1mmMapper->SetTransformCoordinate( normCoords );
//
//    // just for test
//    vtkCoordinate *cd = v1mmMapper->GetTransformCoordinate();
//    assert( nullptr != cd );
//    printf( "GetCoordinateSystemAsString: %s\n", cd->GetCoordinateSystemAsString() );
//
//    double linePoint1[3] = { 0, -1, 0.0 };
//    double linePoint2[3] = { 0, 1, 0.0 };
//    vtkIdType pointId1 = v1mmPoints->InsertNextPoint(linePoint1);
//    vtkIdType pointId2 = v1mmPoints->InsertNextPoint(linePoint2);
//    vtkIdType lineIds[2] = { pointId1, pointId2 };
//    v1mmLines->InsertNextCell(2, lineIds);
//
////    double linePoint11[3] = { 0, -1, 0.5 };
////    double linePoint22[3] = { 0, 1.5, 0.5 };
////    vtkIdType pointId11 = v1mmPoints->InsertNextPoint(linePoint11);
////    vtkIdType pointId22 = v1mmPoints->InsertNextPoint(linePoint22);
////    vtkIdType lineIds1[2] = { pointId11, pointId22 };
////    v1mmLines->InsertNextCell(2, lineIds1);
//
//
//    linePoint1[0] = -1; linePoint1[1] = 0; linePoint1[2] = 0;
//    linePoint2[0] = 1; linePoint2[1] = 0; linePoint2[2] = 0;
//    lineIds[0] = v1mmPoints->InsertNextPoint(linePoint1);
//    lineIds[1] = v1mmPoints->InsertNextPoint(linePoint2);
//    v1mmLines->InsertNextCell(2, lineIds);
//    v1mmPolyData->Modified();
//    // ------------- adding red line finished----------------
//
//    renderer->ResetCamera();
//
//    renderer->AddActor2D( v1mmLinesActor );
//
//    renderWindow->Render();
//    renderWindowInteractor->Start();


    return EXIT_SUCCESS;
}
